/**
 * 游戏状态 Store
 *
 * 职责：
 * - 维护游戏进行状态、计时、当前房间与玩家信息
 * - 维护画布像素数据与玩家统计（面积、得分）
 * - 提供开始/结束/计时、像素增删、统计计算等方法
 */
import { defineStore } from 'pinia'
import { ref, computed, markRaw } from 'vue'
import { gameAPI } from '@/api'
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
import { handleApiResponse } from '@/utils/request'

export const useGameStore = defineStore('game', () => {
  // 游戏状态
  const gameStatus = ref('waiting') // waiting, playing, finished
  const gameTime = ref(120) // 游戏剩余时间（秒）
  const gameTotalDuration = ref(120) // 游戏总时长（秒）
  const gameEndAtMs = ref(null) // 基于服务端 timeLeft 计算的目标结束时间戳（毫秒）
  let gameTimeSyncTimer = null // 基于目标结束时间的统一同步计时器
  const currentPlayer = ref('你')
  const currentRoomId = ref(null)
  const currentRoomName = ref('')
  
  // 玩家数据
  const players = ref([
    { id: 1, name: '小红', color: '#EF4444', score: 35.0, area: 0, isActive: true, avatar: '', isHost: false, isReady: false },
    { id: 2, name: '你', color: '#3B82F6', score: 23.2, area: 0, isActive: true, avatar: '', isHost: true, isReady: false },
    { id: 3, name: '小明', color: '#10B981', score: 18.3, area: 0, isActive: true, avatar: '', isHost: false, isReady: false },
    { id: 4, name: '小丽', color: '#F59E0B', score: 16.5, area: 0, isActive: true, avatar: '', isHost: false, isReady: false },
    { id: 5, name: '小强', color: '#8B5CF6', score: 14.3, area: 0, isActive: true, avatar: '', isHost: false, isReady: false }
  ])
  
  // 画布数据：pixels 使用 "x,y" 作为 key 存储像素信息
  const canvasData = ref({
    width: 800,
    height: 600,
    // 移除 markRaw，确保像素更新能触发响应式更新
    pixels: {} // { '10,20': { color, player, brushSize } }
  })
  
  // 颜色选项（调色板）
  const colors = [
    { name: '红色', value: '#EF4444' },
    { name: '蓝色', value: '#3B82F6' },
    { name: '绿色', value: '#10B981' },
    { name: '橙色', value: '#F59E0B' },
    { name: '紫色', value: '#8B5CF6' }
  ]

  // 游戏统计
  const gameStats = ref({
    playerStats: null,
    leaderboard: [],
    globalStats: null,
    roomStats: null
  })

  // 游戏历史
  const gameHistory = ref({
    history: [],
    currentGame: null,
    playerHistory: [],
    roomHistory: []
  })
  
  // 计算属性
  const sortedPlayers = computed(() => {
    return [...players.value].sort((a, b) => b.score - a.score)
  })
  
  const totalArea = computed(() => {
    return players.value.reduce((sum, player) => sum + player.area, 0)
  })
  
  const currentPlayerData = computed(() => {
    return players.value.find(p => p.name === currentPlayer.value)
  })
  
  // 活跃玩家数量
  const activePlayerCount = computed(() => {
    return players.value.filter(p => p.isActive !== false).length
  })
  
  // 轻量防抖：缩短到 50ms，大幅减少"同步很慢"的体感
  let scoreRecalculationTimer = null
  const debouncedRecalculateScores = () => {
    if (scoreRecalculationTimer) clearTimeout(scoreRecalculationTimer)
    scoreRecalculationTimer = setTimeout(() => {
      // 使用微任务/下一帧降低阻塞风险
      setTimeout(() => {
        recalculateScores()
      }, 0)
    }, 50) // 从120ms减少到50ms，提升响应速度
  }
  
  // 🔧 新增：更新玩家统计信息
  const updatePlayerStats = (playerName, stats) => {
    let player = players.value.find(p => p.name === playerName)
    
    if (!player) {
      // 如果玩家不存在，创建新玩家
      player = {
        id: `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        name: playerName,
        color: '#3B82F6', // 默认蓝色
        score: 0,
        area: 0,
        isActive: true
      }
      players.value.push(player)
    }
    
    // 更新玩家统计
    if (stats.area !== undefined) {
      player.area = stats.area
    }
    if (stats.score !== undefined) {
      player.score = stats.score
    }
    if (stats.isActive !== undefined) {
      player.isActive = stats.isActive
    }
    
    console.log(`✅ 玩家 ${playerName} 统计已更新:`, stats)
  }
  
  // 方法
  // 头像URL解析：将 /avatars/xxx 或文件名规范为 /users/avatar-file/{name} 完整URL
  const resolveAvatarUrl = (fileOrUrl) => {
    try {
      if (!fileOrUrl) return ''
      const base = (request?.defaults?.baseURL || '').replace(/\/+$/, '')
      const toApi = (name) => `${base}/users/avatar-file/${encodeURIComponent(name)}`
      if (typeof fileOrUrl === 'string' && /^(https?:)?\/\//i.test(fileOrUrl)) {
        try {
          const url = new URL(fileOrUrl, window.location.origin)
          const parts = url.pathname.split('/')
          const filename = parts[parts.length - 1]
          if (/\/avatars\//i.test(url.pathname) && filename) return toApi(filename)
        } catch {}
        return fileOrUrl
      }
      if (/\/avatars\//i.test(String(fileOrUrl))) {
        const parts = String(fileOrUrl).split('/')
        const filename = parts[parts.length - 1]
        return filename ? toApi(filename) : ''
      }
      return toApi(String(fileOrUrl))
    } catch { return '' }
  }
  /** 开始游戏 */
  const startGame = async (roomId) => {
    if (gameStatus.value !== 'waiting') {
      console.warn('⚠️ 游戏状态不是等待中，无法开始游戏')
      return false
    }
    
    try {
      console.log('🚀 开始游戏逻辑...')
      
      // 开始前清理无效玩家数据
      cleanupPlayers()
      
      // 通过SignalR调用开始游戏，而不是HTTP API
      console.log('📞 通过SignalR调用StartGame...')
      
      // 导入socketManager
      const socketManager = await import('@/utils/socket').then(module => module.default)
      
      // 检查SignalR连接状态
      const connectionStatus = socketManager.getConnectionStatus()
      console.log('🔍 SignalR连接状态:', connectionStatus)
      
      if (!connectionStatus.isConnected) {
        console.warn('⚠️ SignalR未连接，尝试重新连接...')
        
        try {
          // 尝试重新连接
          await socketManager.connect()
          console.log('✅ SignalR重新连接成功')
          
          // 等待一段时间让连接稳定
          await new Promise(resolve => setTimeout(resolve, 1000))
          
          // 再次检查连接状态
          const newConnectionStatus = socketManager.getConnectionStatus()
          console.log('🔍 重连后连接状态:', newConnectionStatus)
          
          if (!newConnectionStatus.isConnected) {
            console.error('❌ 重连后仍然未连接，状态详情:', newConnectionStatus)
            throw new Error('重新连接后仍然未连接')
          }
        } catch (reconnectError) {
          console.error('❌ SignalR重新连接失败:', reconnectError)
          throw new Error('SignalR连接失败，请检查网络连接并刷新页面重试')
        }
      }
      
      // 确保房主已准备（服务端要求），若未准备则先置为已准备
      try {
        const hostPlayer = players.value.find(p => p.isHost)
        if (hostPlayer) {
          const socketManagerForReady = await import('@/utils/socket').then(m => m.default)
          await socketManagerForReady.playerReady({ roomId, playerId: hostPlayer.id, isReady: true })
          updatePlayerReady(hostPlayer.id, true)
          console.log('✅ 已强制将房主置为已准备')
        }
      } catch (e) {
        console.warn('⚠️ 设置房主准备状态失败(忽略继续):', e?.message)
      }

      // 调用SignalR的StartGame方法
      await socketManager.startGame(roomId)
      console.log('✅ SignalR StartGame调用成功')
      
      // 注意：游戏状态更新将通过SignalR事件通知，不需要在这里手动更新
      // 等待GameStarted事件来更新状态
      
      console.log('🎉 游戏开始请求已发送，等待服务器响应...')
      return true
      
    } catch (error) {
      console.error('❌ 开始游戏失败:', error)
      console.error('错误详情:', {
        message: error.message,
        stack: error.stack,
        response: error.response
      })
      
      // 提供更友好的错误信息
      let userMessage = '开始游戏失败，请重试'
      if (error.message.includes('SignalR连接失败')) {
        userMessage = '网络连接失败，请检查网络并刷新页面重试'
      } else if (error.message.includes('Socket未连接')) {
        userMessage = '实时连接断开，请刷新页面重试'
      } else if (error.message.includes('401') || error.message.includes('Unauthorized')) {
        userMessage = '登录已过期，请重新登录'
      }
      
      // 抛出包含用户友好信息的错误
      const enhancedError = new Error(userMessage)
      enhancedError.originalError = error
      throw enhancedError
    }
  }
  
  /** 结束游戏 */
  const endGame = () => {
    if (gameStatus.value !== 'playing') return
    
    gameStatus.value = 'finished'
    
    // 停止计时器
    if (gameTimeSyncTimer) {
      clearInterval(gameTimeSyncTimer)
      gameTimeSyncTimer = null
    }
    
    // 结束时重置所有玩家的准备状态
    try {
      players.value.forEach(p => { p.isReady = false })
    } catch (_) {}

    // 游戏结束时重新统计所有玩家的面积
    recalculateAllPlayerAreas()

    // 计算最终排名
    const finalRanking = [...players.value]
      .filter(p => p.isActive)
      .sort((a, b) => b.area - a.area)
      .map((player, index) => ({
        ...player,
        rank: index + 1
      }))
    
    // 更新游戏统计
    gameStats.value.leaderboard = finalRanking
    
    console.log('🏁 游戏结束! 最终排名:', finalRanking)
    
    // 触发游戏结束事件
    // emit('game-ended', {
    //   ranking: finalRanking,
    //   winner: finalRanking[0]?.name || '未知'
    // })
  }
  
  /** 重置游戏 */
  const resetGame = () => {
    gameStatus.value = 'waiting'
    gameTime.value = gameTotalDuration.value
    gameEndAtMs.value = null
    
    // 重置所有玩家状态
    players.value.forEach(player => {
      player.area = 0
      player.score = 0
      player.isReady = false
    })
    
    // 清空画布
    canvasData.value.pixels = markRaw({})
    
    // 重置游戏统计
    gameStats.value.leaderboard = []
    
    console.log('🔄 游戏已重置')
  }

  /** 清理无效玩家数据 */
  const cleanupPlayers = () => {
    console.log('🧹 开始清理无效玩家数据...')
    console.log('清理前玩家列表:', players.value)
    
    // 移除测试数据和无效玩家
    const invalidNames = ['占领进度', '小红', '小明', '小丽', '小强', '小刚', '小美', '小华', 'admin', 'admin2']
    const validPlayers = players.value.filter(player => {
      // 排除测试玩家和系统生成的无效数据
      if (invalidNames.includes(player.name)) {
        console.log('🧹 清理无效玩家:', player.name)
        return false
      }
      
      // 确保玩家有有效的ID和名称
      if (!player.id || !player.name || player.name.trim() === '') {
        console.log('🧹 清理无效玩家数据:', player)
        return false
      }
      
      // 检查是否有重复的玩家ID
      const duplicateCount = players.value.filter(p => String(p.id) === String(player.id)).length
      if (duplicateCount > 1) {
        console.log('🧹 清理重复玩家ID:', player.id, '出现次数:', duplicateCount)
        return false
      }
      
      return true
    })
    
    // 如果清理后玩家数量异常，进一步清理
    if (validPlayers.length > 10) {
      console.log('⚠️ 玩家数量异常，进一步清理...')
      const furtherCleaned = validPlayers.slice(0, 5) // 只保留前5个
      players.value = furtherCleaned
      console.log('✅ 玩家数据深度清理完成，剩余玩家:', furtherCleaned.length)
    } else {
      players.value = validPlayers
      console.log('✅ 玩家数据清理完成，剩余玩家:', validPlayers.length)
    }
    
    // 清理画布数据中的无效像素
    if (canvasData.value.pixels) {
      const validPixelKeys = Object.keys(canvasData.value.pixels).filter(key => {
        const pixel = canvasData.value.pixels[key]
        if (!pixel || !pixel.player || !pixel.color) {
          return false
        }
        // 检查像素对应的玩家是否还存在
        const playerExists = players.value.some(p => p.name === pixel.player)
        if (!playerExists) {
          console.log('🧹 清理无效像素:', key, '玩家不存在:', pixel.player)
          return false
        }
        return true
      })
      
      const cleanedPixels = {}
      validPixelKeys.forEach(key => {
        cleanedPixels[key] = canvasData.value.pixels[key]
      })
      
      canvasData.value.pixels = cleanedPixels
      console.log('✅ 画布像素清理完成，剩余像素:', validPixelKeys.length)
    }
  }
  
  /** 强制清理多余玩家数据 */
  const cleanupExtraPlayers = () => {
    console.log('🧹 开始强制清理多余玩家数据...')
    console.log('清理前玩家列表:', players.value)
    
    // 获取房间成员数量
    const expectedPlayerCount = 2 // 预期只有2个玩家
    
    // 如果玩家数量超过预期，强制清理
    if (players.value.length > expectedPlayerCount) {
      console.log(`⚠️ 玩家数量异常: ${players.value.length} > ${expectedPlayerCount}，开始强制清理...`)
      
      // 只保留前2个有效玩家
      const validPlayers = players.value.slice(0, expectedPlayerCount).filter(player => {
        // 确保玩家有有效的ID和名称
        if (!player.id || !player.name || player.name.trim() === '') {
          console.log('🧹 清理无效玩家数据:', player)
          return false
        }
        return true
      })
      
      players.value = validPlayers
      console.log('✅ 多余玩家强制清理完成，剩余玩家:', validPlayers.length)
      
      // 同时清理画布数据
      if (canvasData.value.pixels) {
        const validPixelKeys = Object.keys(canvasData.value.pixels).filter(key => {
          const pixel = canvasData.value.pixels[key]
          if (!pixel || !pixel.player || !pixel.color) {
            return false
          }
          // 检查像素对应的玩家是否还存在
          const playerExists = validPlayers.some(p => p.name === pixel.player)
          if (!playerExists) {
            console.log('🧹 清理无效像素:', key, '玩家不存在:', pixel.player)
            return false
          }
          return true
        })
        
        const cleanedPixels = {}
        validPixelKeys.forEach(key => {
          cleanedPixels[key] = canvasData.value.pixels[key]
        })
        
        canvasData.value.pixels = cleanedPixels
        console.log('✅ 画布像素强制清理完成，剩余像素:', validPixelKeys.length)
      }
    } else {
      console.log('✅ 玩家数量正常，无需强制清理')
    }
  }
  
  /** 更新玩家准备状态 */
  const updatePlayerReady = (playerId, isReady) => {
    const player = players.value.find(p => p.id === playerId)
    if (player) {
      player.isReady = isReady
      console.log(`玩家 ${player.name} 准备状态: ${isReady ? '已准备' : '未准备'}`)
    }
  }
  
  /** 检查是否所有玩家都准备好了 */
  const allPlayersReady = computed(() => {
    const activePlayers = players.value.filter(p => p.isActive)
    // 为了测试目的，允许至少有一个玩家准备就绪就可以开始游戏
    // 在实际生产环境中，应该要求所有玩家都准备就绪
    return activePlayers.length > 0 && activePlayers.some(p => p.isReady)
  })
  
  /** 校验颜色是否已分配（非默认占位色） */
  const hasValidColor = (color) => {
    if (!color || typeof color !== 'string') return false
    const c = color.toUpperCase()
    // '#6B7280' 为前端占位灰；'#3B82F6' 为默认蓝
    return c !== '#6B7280'.toUpperCase() && c !== '#3B82F6'.toUpperCase()
  }

  // 颜色稳定化：按房间+玩家ID缓存一次有效颜色，后续同步优先使用缓存
  const colorStorageKey = (playerId) => `roomColor:${currentRoomId.value || 'NA'}:${playerId}`
  const getStoredColor = (playerId) => {
    try { return localStorage.getItem(colorStorageKey(playerId)) || null } catch { return null }
  }
  const storeColor = (playerId, color) => {
    try { if (hasValidColor(color)) localStorage.setItem(colorStorageKey(playerId), color) } catch {}
  }
  const getStableColor = (playerId, proposedColor, previousColor) => {
    const stored = getStoredColor(playerId)
    if (hasValidColor(stored)) return stored
    const chosen = hasValidColor(previousColor) ? previousColor : (hasValidColor(proposedColor) ? proposedColor : (previousColor || proposedColor))
    if (hasValidColor(chosen)) storeColor(playerId, chosen)
    return chosen
  }

  /** 所有活跃玩家是否都有颜色 */
  const allPlayersHaveColors = computed(() => {
    const activePlayers = players.value.filter(p => p.isActive)
    if (activePlayers.length === 0) return false
    return activePlayers.every(p => hasValidColor(p.color))
  })

  /** 检查是否可以开始游戏 */
  const canStartGame = computed(() => {
    return gameStatus.value === 'waiting' && 
           activePlayerCount.value >= 2 && 
           allPlayersReady.value &&
           allPlayersHaveColors.value
  })
  
  /** 处理涂色动作 */
  const handlePaintAction = (paintData) => {
    if (gameStatus.value !== 'playing') return
    const { x, y, color, player, brushSize } = paintData
    
    // 更新画布像素
    const pixelKey = `${x},${y}`
    canvasData.value.pixels[pixelKey] = {
      color,
      player,
      brushSize,
      timestamp: Date.now()
    }
    
    // 更新玩家面积
    const playerData = players.value.find(p => p.name === player)
    if (playerData) {
      playerData.area += 1
      // 触发分数重新计算
      recalculateScores()
    }
    
    console.log(`🎨 涂色动作: ${player} 在 (${x}, ${y}) 涂色`)
  }
  
  /** 处理画布重置 */
  const handleCanvasReset = () => {
    // 清空画布
    canvasData.value.pixels = markRaw({})
    
    // 重置所有玩家面积
    players.value.forEach(player => {
      player.area = 0
      player.score = 0
      player.isReady = false
    })
    
    // 重置游戏状态
    gameStatus.value = 'waiting'
    gameTime.value = gameTotalDuration.value
    
    console.log('🔄 画布已重置')
  }
  
  /** 处理游戏结束 */
  const handleGameEnded = (gameData) => {
    const { ranking, winner } = gameData
    
    gameStatus.value = 'finished'
    gameTime.value = 0
    
    // 更新排行榜
    gameStats.value.leaderboard = ranking
    
    // 更新玩家排名
    ranking.forEach((player, index) => {
      const existingPlayer = players.value.find(p => p.id === player.id)
      if (existingPlayer) {
        existingPlayer.rank = index + 1
        existingPlayer.area = player.area
        existingPlayer.score = player.score
      }
    })
    
    console.log(`🏁 游戏结束! 获胜者: ${winner}`)
    
    // 停止计时器
    if (gameTimeSyncTimer) {
      clearInterval(gameTimeSyncTimer)
      gameTimeSyncTimer = null
    }
  }
  
  /** 处理房间成员更新 */
  const handleRoomMembersUpdated = (members) => {
    if (!Array.isArray(members)) return
    
    // 更新玩家列表
    const updatedPlayers = members.map(member => ({
      id: member.id,
      name: member.name,
      color: member.color,
      avatar: member.avatar || '',
      isReady: member.isReady || false,
      isHost: member.isHost || false,
      area: member.areaCount || 0,
      score: 0,
      isActive: true
    }))
    
    setPlayers(updatedPlayers)
    console.log('👥 房间成员已更新:', updatedPlayers.length, '人')
  }
  
  /** 处理排行榜更新 */
  const handleLeaderboardUpdated = (leaderboardData) => {
    if (!leaderboardData || !Array.isArray(leaderboardData.leaderboard)) return
    
    // 更新排行榜
    gameStats.value.leaderboard = leaderboardData.leaderboard
    
    // 同步更新玩家面积
    leaderboardData.leaderboard.forEach(entry => {
      const player = players.value.find(p => p.id === entry.playerId)
      if (player) {
        player.area = entry.areaCount || 0
      }
    })
    
    // 重新计算分数
    recalculateScores()
    
    console.log('📊 排行榜已更新')
  }
  
  /**
   * 设置剩余时间；当时间耗尽时自动结束游戏
   */
  const updateGameTime = (time) => {
    gameTime.value = time
    if (time <= 0) {
      endGame()
    }
  }
  
  /** 直接设置游戏时间（秒） */
  const setGameTime = (time) => {
    gameTime.value = time
  }

  // 启动统一的基于服务端 endAt 的计时器（每个客户端都以相同 endAt 计算，避免各自累加误差）
  const startSyncedGameTimer = () => {
    if (!gameEndAtMs.value) return
    if (gameTimeSyncTimer) clearInterval(gameTimeSyncTimer)
    gameTimeSyncTimer = setInterval(() => {
      const now = Date.now()
      const left = Math.max(0, Math.floor((gameEndAtMs.value - now) / 1000))
      if (left !== gameTime.value) gameTime.value = left
      if (left <= 0 && gameStatus.value === 'playing') {
        endGame()
      }
    }, 1000)
  }
  
  /** 设置当前房间信息 */
  const setCurrentRoom = (roomId, roomName, maxPlayers = 5, durationMinutes) => {
    currentRoomId.value = roomId
    currentRoomName.value = roomName
    // 若传入了房间时长（分钟），作为新的总时长
    if (typeof durationMinutes === 'number' && durationMinutes > 0) {
      gameTotalDuration.value = Math.floor(durationMinutes * 60)
      gameTime.value = gameTotalDuration.value
    }
    
    // 根据最大玩家数生成玩家列表
    generatePlayersList(maxPlayers)
  }
  
  /** 根据最大玩家数生成玩家列表 */
  const generatePlayersList = (maxPlayers = 5) => {
    const playerNames = ['你', '小红', '小明', '小丽', '小强', '小刚', '小美', '小华']
    const playerColors = ['#3B82F6', '#EF4444', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16']
    
    const newPlayers = []
    for (let i = 0; i < maxPlayers; i++) {
      newPlayers.push({
        id: i + 1,
        name: playerNames[i] || `玩家${i + 1}`,
        color: playerColors[i] || '#6B7280',
        score: 0,
        area: 0,
        isActive: false, // 标记玩家是否活跃
        avatar: '', // 玩家头像
        isHost: i === 0, // 第一个玩家是房主
        isReady: false // 准备状态
      })
    }
    
    players.value = newPlayers
    console.log(`生成了${maxPlayers}人玩家列表:`, players.value)
  }

  /** 直接设置玩家列表（用于实时同步房间成员） */
  const setPlayers = (newPlayers) => {
    if (!Array.isArray(newPlayers)) {
      console.warn('setPlayers: 传入的参数不是数组:', newPlayers)
      return
    }
    // 先构建现有玩家的快速索引，便于保留已分配的颜色
    const prevById = new Map(players.value.map(p => [String(p.id), p]))
    const isPlaceholder = (c) => {
      if (!c || typeof c !== 'string') return true
      const u = c.toUpperCase()
      return u === '#6B7280' || u === '#3B82F6'
    }

    players.value = newPlayers.map(player => {
      const prev = prevById.get(String(player.id))
      const incomingColor = player.color
      const color = getStableColor(player.id, incomingColor, prev?.color)
      return {
        ...player,
        color,
        score: player.score || 0,
        area: player.area || 0,
        level: typeof player.level === 'number' ? player.level : (prev && typeof prev.level === 'number' ? prev.level : 1),
        title: typeof player.title === 'string' && player.title ? player.title : (prev && prev.title ? prev.title : '墨痕初绽'),
        isActive: player.isActive !== undefined ? player.isActive : true
      }
    })
    
    console.log('玩家列表已更新，当前玩家数:', players.value.length)
  }
  
  /** 清空房间与状态回到等待 */
  const resetRoom = () => {
    currentRoomId.value = null
    currentRoomName.value = ''
    gameStatus.value = 'waiting'
  }
  
  /** 更新指定玩家分数（非百分比的原始值） */
  
  /** 更新指定玩家占地面积（像素数），并联动更新百分比分数 */
  const updatePlayerArea = (playerId, area) => {
    const player = players.value.find(p => p.id === playerId)
    if (player) {
      player.area = area
      // 重新计算百分比
      recalculateScores()
    }
  }
  
  /** 重新计算所有玩家的面积（基于画布像素数据） */
  const recalculateAllPlayerAreas = () => {
    // 保存当前的活跃状态
    const activeStatus = players.value.reduce((acc, player) => {
      acc[player.id] = player.isActive
      return acc
    }, {})
    
    // 重置所有玩家面积
    players.value.forEach(player => {
      player.area = 0
    })
    
    // 根据画布像素重新计算面积和活跃状态
    Object.values(canvasData.value.pixels).forEach(pixel => {
      let player = players.value.find(p => p.name === pixel.player)
      
      // 如果玩家不存在，自动创建新玩家
      if (!player) {
        console.log(`🔄 重新计算时自动创建新玩家: ${pixel.player}`)
        
        // 创建新玩家
        player = {
          id: `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          name: pixel.player,
          // 用像素自身的颜色作为玩家颜色
          color: pixel.color || '#3B82F6',
          score: 0,
          area: 0,
          isActive: true
        }
        
        // 添加到玩家列表
        players.value.push(player)
        console.log('✅ 重新计算时新玩家已添加到列表:', player)
      }
      
      if (player) {
        const areaWeight = Math.max(1, pixel.brushSize || 1)
        player.area += areaWeight
        player.isActive = true // 有像素的玩家标记为活跃
      }
    })
    
    // 恢复没有像素但之前在房间中的玩家的活跃状态
    players.value.forEach(player => {
      if (player.area === 0 && activeStatus[player.id] === true) {
        player.isActive = true
      }
    })
    
    console.log('重新计算所有玩家面积和活跃状态:', players.value.map(p => ({ name: p.name, area: p.area, isActive: p.isActive })))
    
    // 重新计算分数
    recalculateScores()
  }
  
  /** 🔧 优化：按玩家当前面积与总面积计算百分比分数（保留 1 位小数） */
  const recalculateScores = () => {
    // 直接计算总面积，避免循环依赖
    const total = players.value.reduce((sum, player) => sum + player.area, 0)
    
    if (total > 0) {
      players.value.forEach(player => {
        const newScore = Math.round((player.area / total) * 100 * 10) / 10
        player.score = newScore
      })
    } else {
      // 如果总面积为0，所有玩家分数为0
      players.value.forEach(player => {
        player.score = 0
      })
    }
  }
  
  /** 清空画布与玩家统计 */
  const resetCanvas = () => {
    canvasData.value.pixels = markRaw({})
    // 清空像素缓存
    // pixelCache.clear() // 移除像素缓存，避免重复检查导致的延迟
    // 重置所有玩家面积、分数和活跃状态
    players.value.forEach(player => {
      player.area = 0
      player.score = 0
      player.isActive = false
    })
    console.log('画布已重置，所有玩家面积、分数和活跃状态已清零')
  }
  
  // 批量更新队列
  let pixelUpdateQueue = []
  let isProcessingUpdates = false
  // const scoreUpdateTimer = null // 可能用于未来的分数更新优化
  // const pixelCache = new Set() // 移除像素缓存，避免重复检查导致的延迟
  
  /** 处理像素更新队列 - 立即处理，无延迟 */
  const processPixelUpdates = () => {
    if (gameStatus.value !== 'playing') return
    
    // 直接处理，无需setTimeout
    const updates = pixelUpdateQueue.splice(0)
    
    updates.forEach(update => {
      const { x, y, color, playerName, playerId, brushSize = 1 } = update
      
      // 立即更新画布数据
      const key = `${x},${y}`
      canvasData.value[key] = {
        x,
        y,
        color,
        playerName,
        playerId,
        timestamp: Date.now()
      }
      
      // 立即更新玩家面积
      const player = players.value.find(p => 
        p.name === playerName || p.id === playerId || p.id === playerName
      )
      
      if (player) {
        player.area = (Number(player.area) || 0) + brushSize
      }
    })
    
    // 批量更新后重新计算分数
    if (updates.length > 0) {
      recalculateScores()
    }
  }
  
  /** 添加像素到队列并立即处理 */
  const addPixel = (pixelData) => {
    if (gameStatus.value !== 'playing') return
    
    const { x, y, color, playerName, playerId, brushSize = 1 } = pixelData
    
    // 立即更新画布数据
    const key = `${x},${y}`
    
    // 直接更新像素，现在 pixels 是响应式的
    canvasData.value.pixels[key] = {
      x,
      y,
      color,
      playerName,
      playerId,
      timestamp: Date.now()
    }
    
    console.log('✅ addPixel: 像素已更新到 canvasData.pixels:', key, canvasData.value.pixels[key])
    console.log('📊 addPixel: 当前 pixels 总数:', Object.keys(canvasData.value.pixels).length)
    
    // 立即更新玩家面积
    const player = players.value.find(p => 
      p.name === playerName || p.id === playerId || p.id === playerName
    )
    
    if (player) {
      player.area = (Number(player.area) || 0) + brushSize
      // 直接重新计算分数，无需debounce
      recalculateScores()
    }
  }
  
  /** 获取像素颜色 */
  const getPixelColor = (x, y) => {
    const key = `${x},${y}`
    return canvasData.value.pixels[key]?.color || null
  }
  
  /** 获取像素归属玩家 */
  const getPixelPlayer = (x, y) => {
    const key = `${x},${y}`
    return canvasData.value.pixels[key]?.player || null
  }
  
  /** 清除指定玩家的所有像素，并重算统计 */
  const clearPlayerPixels = (playerName) => {
    // 清除指定玩家的所有像素
    Object.keys(canvasData.value.pixels).forEach(key => {
      if (canvasData.value.pixels[key].player === playerName) {
        delete canvasData.value.pixels[key]
      }
    })
    
    // 重新计算所有玩家的面积和分数
    recalculateAllPlayerAreas()
  }
  
  /** 获取玩家统计摘要（像素总数、占比等） */
  const getPlayerStats = (playerName) => {
    const player = players.value.find(p => p.name === playerName)
    if (!player) return null
    
    const totalPixels = Object.keys(canvasData.value.pixels).length
    const playerPixels = Object.values(canvasData.value.pixels).filter(
      pixel => pixel.player === playerName
    ).length
    
    return {
      name: player.name,
      color: player.color,
      area: player.area,
      score: player.score,
      pixelCount: playerPixels,
      totalPixels,
      percentage: totalPixels > 0 ? Math.round((playerPixels / totalPixels) * 100 * 10) / 10 : 0
    }
  }

  // ========================================
  // 🎨 画布API相关方法
  // ========================================

  // 记录绘画动作
  const recordPaintAction = async (paintData) => {
    try {
      if (!currentRoomId.value) {
        console.warn('未在房间中，跳过API记录')
        return { success: false, reason: 'no_room' }
      }
      
      const data = {
        roomId: currentRoomId.value,
        x: paintData.x,
        y: paintData.y,
        color: paintData.color,
        tool: paintData.tool || 'brush'
      }
      
      await gameAPI.paintAction(data)
      return { success: true }
    } catch (error) {
      console.warn('记录绘画动作失败（不影响本地功能）:', error.message)
      return { success: false, error: error.message }
    }
  }

  // 获取画布数据
  const fetchCanvasData = async (roomId) => {
    try {
      const result = await gameAPI.getCanvasData(roomId)
      const canvasResult = handleApiResponse(result, 'data')
      if (canvasResult && canvasResult.pixels) {
        canvasData.value.pixels = markRaw(canvasResult.pixels)
      }
      return result
    } catch (error) {
      console.error('获取画布数据失败:', error)
      throw error
    }
  }

  // 重置画布
  const resetCanvasAPI = async (roomId) => {
    try {
      await gameAPI.resetCanvas(roomId)
      resetCanvas()
      ElMessage.success('画布已重置')
    } catch (error) {
      console.error('重置画布失败:', error)
      throw error
    }
  }

  // ========================================
  // 📊 统计API相关方法
  // ========================================

  // 获取玩家统计
  const fetchPlayerStats = async (userId) => {
    try {
      const result = await gameAPI.getPlayerStats(userId)
      const statsData = handleApiResponse(result, 'data')
      gameStats.value.playerStats = statsData
      return result
    } catch (error) {
      console.error('获取玩家统计失败:', error)
      throw error
    }
  }

  // 获取排行榜
  const fetchLeaderboard = async (params = {}) => {
    try {
      const result = await gameAPI.getLeaderboard(params)
      const leaderboardData = handleApiResponse(result, 'data')
      gameStats.value.leaderboard = Array.isArray(leaderboardData) ? leaderboardData : []
      return result
    } catch (error) {
      console.error('获取排行榜失败:', error)
      throw error
    }
  }

  // 获取全局统计
  const fetchGlobalStats = async () => {
    try {
      const result = await gameAPI.getGlobalStats()
      const statsData = handleApiResponse(result, 'data')
      gameStats.value.globalStats = statsData
      return result
    } catch (error) {
      console.error('获取全局统计失败:', error)
      throw error
    }
  }

  // 获取房间统计
  const fetchRoomStats = async (roomId) => {
    try {
      const result = await gameAPI.getRoomStats(roomId)
      const statsData = handleApiResponse(result, 'data')
      gameStats.value.roomStats = statsData
      return result
    } catch (error) {
      console.error('获取房间统计失败:', error)
      throw error
    }
  }

  // ========================================
  // 🔄 实时数据更新方法
  // ========================================

  // 实时更新玩家数据
  const updatePlayerData = (playerData) => {
    if (!playerData || !playerData.id) {
      console.warn('无效的玩家数据:', playerData)
      return
    }

    console.log('更新玩家数据，接收到的颜色:', playerData.color)

    const existingPlayerIndex = players.value.findIndex(p => String(p.id) === String(playerData.id))
    
    if (existingPlayerIndex !== -1) {
      // 更新现有玩家数据（字段名兼容：name/username，area/areaCount，avatar为预览URL由外层已处理）
      const prev = players.value[existingPlayerIndex]
      const keepPrevColor = hasValidColor(prev?.color)
      const prevLevel = players.value[existingPlayerIndex].level
      const prevTitle = players.value[existingPlayerIndex].title
      const incoming = {
        id: playerData.id,
        name: playerData.name || playerData.username,
        // 若已有有效颜色，保持不变；仅当此前无效色时才采用服务端颜色
        color: keepPrevColor ? prev.color : playerData.color,
        area: typeof playerData.area === 'number' ? playerData.area : (typeof playerData.areaCount === 'number' ? playerData.areaCount : players.value[existingPlayerIndex].area),
        score: typeof playerData.score === 'number' ? playerData.score : players.value[existingPlayerIndex].score,
        isReady: typeof playerData.isReady === 'boolean' ? playerData.isReady : players.value[existingPlayerIndex].isReady,
        isHost: typeof playerData.isHost === 'boolean' ? playerData.isHost : players.value[existingPlayerIndex].isHost,
        avatar: resolveAvatarUrl(playerData.avatar) || players.value[existingPlayerIndex].avatar,
        // 等级/称号以服务端为准；仅当服务端未提供时保留本地已有（且不默认为1或默认称号）
        level: (typeof playerData.level === 'number') ? playerData.level : (prevLevel !== undefined && prevLevel !== null ? prevLevel : undefined),
        title: (typeof playerData.title === 'string' && playerData.title) ? playerData.title : (prevTitle !== undefined && prevTitle !== null ? prevTitle : undefined),
        isActive: true
      }
      players.value[existingPlayerIndex] = { ...players.value[existingPlayerIndex], ...incoming }
      console.log('更新玩家数据:', incoming.name, '颜色:', incoming.color)
    } else {
      // 添加新玩家（字段名兼容）
      const newPlayer = {
        id: playerData.id,
        name: playerData.name || playerData.username || `玩家${players.value.length + 1}`,
        color: playerData.color || getRandomColor(),
        score: typeof playerData.score === 'number' ? playerData.score : 0,
        area: typeof playerData.area === 'number' ? playerData.area : (typeof playerData.areaCount === 'number' ? playerData.areaCount : 0),
        isActive: true,
        isReady: Boolean(playerData.isReady),
        isHost: Boolean(playerData.isHost),
        avatar: resolveAvatarUrl(playerData.avatar) || '',
        level: typeof playerData.level === 'number' ? playerData.level : undefined,
        title: typeof playerData.title === 'string' ? playerData.title : undefined
      }
      players.value.push(newPlayer)
      console.log('添加新玩家:', newPlayer.name, '颜色:', newPlayer.color)
    }
  }

  // 实时更新玩家分数和面积
  const updatePlayerScore = (playerId, score, area) => {
    const player = players.value.find(p => p.id === playerId)
    if (player) {
      if (typeof score === 'number' && !Number.isNaN(score)) {
        player.score = score
      }
      if (typeof area === 'number' && !Number.isNaN(area)) {
        player.area = area
      }
      player.isActive = true
      console.log('更新玩家分数:', player.name, '分数:', score, '面积:', area)
    }
  }

  // 获取总面积（用于调试/显示）
  const getTotalArea = () => players.value.reduce((s, p) => s + (p.area || 0), 0)

  // 实时更新房间成员列表（从房间store同步）
  const updateRoomMembers = (members) => {
    if (!members || !Array.isArray(members)) {
      console.log('无效的成员数据:', members)
      return
    }

    console.log('更新房间成员列表:', members.length, '个成员')
    console.log('成员详细数据:', members)
    
    // 将房间成员转换为游戏玩家格式，使用后端分配的颜色
    const prevById = new Map(players.value.map(p => [String(p.id), p]))
    const gamePlayers = members.map((member, index) => {
      const playerId = member.id || member.userId || `player_${index}`
      const playerName = member.name || member.username || member.nickname || `玩家${index + 1}`
      
      console.log(`处理成员 ${index}:`, {
        id: playerId,
        name: playerName,
        color: member.color,
        avatar: member.avatar
      })
      
      const prev = prevById.get(String(playerId))
      const incomingColor = member.color || '#6B7280'
      const color = getStableColor(playerId, incomingColor, prev?.color)

      return {
        id: playerId,
        name: playerName,
        color,
        score: 0, // 初始分数
        area: 0,  // 初始面积
        isActive: true, // 在房间中的玩家都是活跃的
        isReady: member.isReady || false,
        isHost: member.isHost || false,
        avatar: member.avatar || '', // 同步头像
        // 等级/称号：优先使用服务端；若未提供则保留已有或默认
        level: (typeof member.level === 'number') ? member.level : ((prev && prev.level !== undefined && prev.level !== null) ? prev.level : 1),
        title: (typeof member.title === 'string' && member.title) ? member.title : ((prev && prev.title) ? prev.title : '墨痕初绽')
      }
    })
    
    // 更新玩家列表
    players.value = gamePlayers
    console.log('更新房间成员列表(合并):', players.value.length, '个玩家')
    console.log('最终玩家列表:', players.value)
  }

  // 同步用户头像和分配颜色
  const syncUserAvatarsAndColors = async (roomMembers, userStore) => {
    if (!roomMembers || !Array.isArray(roomMembers)) {
      console.log('无效的成员数据，无法同步头像')
      return
    }

    console.log('开始同步用户头像和颜色...')
    console.log('房间成员数据:', roomMembers)

    // 为每个成员同步头像，使用后端分配的颜色
    const prevById = new Map(players.value.map(p => [String(p.id), p]))
    const updatedPlayers = roomMembers.map((member, index) => {
      const playerId = member.id || member.userId || `player_${index}`
      const playerName = member.name || member.username || member.nickname || `玩家${index + 1}`
      
      // 使用后端分配的颜色，如果没有则使用默认颜色
      const incomingColor = member.color || '#6B7280'
      const prev = prevById.get(String(playerId))
      const color = getStableColor(playerId, incomingColor, prev?.color)
      
      // 获取头像URL
      let avatarUrl = ''
      if (member.avatar) {
        console.log(`成员 ${playerName} 有头像数据:`, member.avatar)
        // 统一从 userStore 取预览地址（与大厅一致），没有则回退后端文件接口
        const preview = (userStore && typeof userStore.getAvatarPreviewUrl === 'function')
          ? userStore.getAvatarPreviewUrl(member.avatar)
          : ''
        avatarUrl = preview || ''
      } else {
        console.log(`成员 ${playerName} 没有头像数据`)
      }
      
      const player = {
        id: playerId,
        name: playerName,
        color: color,
        score: 0,
        area: 0,
        isActive: true,
        isReady: Boolean(member.isReady),
        isHost: Boolean(member.isHost),
        avatar: avatarUrl,
        // 等级/称号仅首次赋值
        level: (prev && prev.level !== undefined && prev.level !== null) ? prev.level : (typeof member.level === 'number' ? member.level : 1),
        title: (prev && prev.title) ? prev.title : (member.title || '墨痕初绽')
      }
      
      console.log(`创建玩家对象:`, player)
      return player
    })
    
    // 更新玩家列表
    players.value = updatedPlayers
    console.log('同步完成，玩家列表已更新:', players.value)
  }

  // 实时更新游戏状态
  const updateGameStatus = (status, timeLeft, startTimeMs, durationSeconds) => {
    if (startTimeMs && durationSeconds) {
      // 优先使用服务器的开始时间 + 总时长，避免网络延迟带来的初始偏差
      gameTotalDuration.value = Number(durationSeconds)
      gameEndAtMs.value = Number(startTimeMs) + Number(durationSeconds) * 1000
      startSyncedGameTimer()
      const left = Math.max(0, Math.floor((gameEndAtMs.value - Date.now()) / 1000))
      gameTime.value = left
      // 如果剩余<=0，强制进入结束态，避免服务端状态延迟
      if (left <= 0) {
        gameStatus.value = 'finished'
      } else if (status) {
        gameStatus.value = status
      }
    } else if (timeLeft !== undefined) {
      // 后备：仅收到剩余秒数时，以本地当前时间基准计算
      // 如果没有总时长信息，假设当前剩余时间就是总时长
      if (!gameTotalDuration.value || gameTotalDuration.value === 120) {
        gameTotalDuration.value = Number(timeLeft) || 120
      }
      gameEndAtMs.value = Date.now() + (Number(timeLeft) || 0) * 1000
      startSyncedGameTimer()
      // 立即同步一次显示，避免下一秒才更新
      const left = Math.max(0, Math.floor((gameEndAtMs.value - Date.now()) / 1000))
      gameTime.value = left
      if (left <= 0) {
        gameStatus.value = 'finished'
      } else if (status) {
        gameStatus.value = status
      }
    } else if (status) {
      gameStatus.value = status
    }
    console.log('更新游戏状态:', status, '剩余时间:', timeLeft)
  }

  // 实时更新画布像素
  const updateCanvasPixel = (pixelData) => {
    console.log('🎨 updateCanvasPixel 被调用:', pixelData)
    if (gameStatus.value !== 'playing') {
      console.log('❌ 游戏状态不是 playing，忽略像素更新')
      return
    }
    
    const { x, y, color, playerName, playerId, brushSize = 1 } = pixelData
    
    // 检查像素是否已存在且相同
    const key = `${x},${y}`
    const existingPixel = canvasData.value.pixels[key]
    
    // 如果像素已存在且颜色相同，跳过更新
    if (existingPixel && existingPixel.color === color) {
      console.log('🔄 像素已存在且颜色相同，跳过更新:', key)
      return
    }
    
    // 立即更新玩家面积（无需debounce）
    const player = players.value.find(p => 
      p.name === playerName || p.id === playerId || p.id === playerName
    )
    
    if (player) {
      // 立即增加面积，提供即时反馈
      player.area = (Number(player.area) || 0) + brushSize
      // 直接重新计算分数，无需debounce
      recalculateScores()
    }
    
    // 更新画布数据
    // 直接更新像素，现在 pixels 是响应式的
    canvasData.value.pixels[key] = {
      x,
      y,
      color,
      playerName,
      playerId,
      brushSize,
      timestamp: Date.now()
    }
    
    console.log('✅ 像素已更新到 canvasData.pixels:', key, canvasData.value.pixels[key])
    console.log('📊 当前 pixels 总数:', Object.keys(canvasData.value.pixels).length)
  }

  // 生成随机颜色
  const getRandomColor = () => {
    const colors = ['#EF4444', '#3B82F6', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16']
    return colors[Math.floor(Math.random() * colors.length)]
  }

  // ========================================
  // 📈 历史记录API相关方法
  // ========================================

  // 获取游戏历史
  const fetchGameHistory = async (params = {}) => {
    try {
      const result = await gameAPI.getGameHistory(params)
      const historyData = handleApiResponse(result, 'data')
      gameHistory.value.history = Array.isArray(historyData) ? historyData : []
      return result
    } catch (error) {
      console.error('获取游戏历史失败:', error)
      throw error
    }
  }

  // 获取特定游戏记录
  const fetchGameRecord = async (gameId) => {
    try {
      const result = await gameAPI.getGameRecord(gameId)
      const recordData = handleApiResponse(result, 'data')
      gameHistory.value.currentGame = recordData
      return result
    } catch (error) {
      console.error('获取游戏记录失败:', error)
      throw error
    }
  }

  // 获取玩家游戏历史
  const fetchPlayerGameHistory = async (userId, params = {}) => {
    try {
      const result = await gameAPI.getPlayerGameHistory(userId, params)
      const historyData = handleApiResponse(result, 'data')
      gameHistory.value.playerHistory = Array.isArray(historyData) ? historyData : []
      return result
    } catch (error) {
      console.error('获取玩家游戏历史失败:', error)
      throw error
    }
  }

  // 获取房间游戏历史
  const fetchRoomGameHistory = async (roomId, params = {}) => {
    try {
      const result = await gameAPI.getRoomGameHistory(roomId, params)
      const historyData = handleApiResponse(result, 'data')
      gameHistory.value.roomHistory = Array.isArray(historyData) ? historyData : []
      return result
    } catch (error) {
      console.error('获取房间游戏历史失败:', error)
      throw error
    }
  }
  
  return {
    // 状态
    gameStatus,
    gameTime,
    gameTotalDuration,
    currentPlayer,
    currentRoomId,
    currentRoomName,
    players,
    canvasData,
    colors,
    gameStats,
    gameHistory,
    
    // 计算属性
    sortedPlayers,
    totalArea,
    currentPlayerData,
    activePlayerCount,
    allPlayersReady,
    canStartGame,
    
    // 基础方法
    startGame,
    endGame,
    resetGame,
    cleanupPlayers,
    cleanupExtraPlayers,
    updatePlayerReady,
    updateGameTime,
    setGameTime,
    setCurrentRoom,
    generatePlayersList,
    setPlayers,
    resetRoom,
    updatePlayerScore,
    updatePlayerArea,
    recalculateScores,
    recalculateAllPlayerAreas,
    resetCanvas,
    addPixel,
    getPixelColor,
    getPixelPlayer,
    clearPlayerPixels,
    getPlayerStats,
    
    // 画布API方法
    recordPaintAction,
    fetchCanvasData,
    resetCanvasAPI,
    handlePaintAction,
    handleCanvasReset,
    handleGameEnded,
    
    // 统计API方法
    fetchPlayerStats,
    fetchLeaderboard,
    fetchGlobalStats,
    fetchRoomStats,
    handleLeaderboardUpdated,
    
    // 历史记录API方法
    fetchGameHistory,
    fetchGameRecord,
    fetchPlayerGameHistory,
    fetchRoomGameHistory,
    
    // 实时数据更新方法
    updatePlayerData,
    updatePlayerScore,
    updatePlayerStats,
    updateRoomMembers,
    syncUserAvatarsAndColors,
    updateGameStatus,
    updateCanvasPixel,
    getTotalArea
  }
}) 